﻿/* patch IE8 to redefine console and console.log */
if (typeof console === "undefined" || typeof console.log === "undefined") {
    console = {};
    console.log = function () { };
}

var AricieLuceneSearchAutocomplete = (function () {
    "use strict";

    return {
        INIT_RAN: {},

        LogFirstRun: function (t, i) {
            var self = this;
            if (self.INIT_RAN[i] === 1) {
                console.log(t);
            }
        },

        CompareVersions: function (version1, version2) {
            var v1parts = version1.split('.');
            var v2parts = version2.split('.');

            for (var i = 0; i < Math.min(v1parts.length, v2parts.length); ++i) {
                var v1Int = parseInt(v1parts[i]);
                var v2Int = parseInt(v2parts[i]);
                if (v1Int != v2Int) {
                    return v1Int < v2Int ? 1 : -1;
                }
            }

            if (v1parts.length != v2parts.length) {
                return v1parts.length < v2parts.length ? 1 : -1;
            }
            return 0;
        },

        Init: function (sms, acs) {
            var self = this;

            if (self.INIT_RAN[acs.targetId] === undefined) {
                self.INIT_RAN[acs.targetId] = 0;
            }
            if (self.INIT_RAN[acs.targetId] > 2) {
                console.log("ERROR: Cannot load jQueryUI. Autocomplete disabled.");
                return;
            }
            self.INIT_RAN[acs.targetId] = self.INIT_RAN[acs.targetId] + 1;

            if (sms.includeScriptAndStyle) { // première vérification pour jQuery
                if (sms.jQueryJSUrl !== "") { // on a une url
                    var jQueryUndefined = (window.jQuery === undefined || self.CompareVersions(window.jQuery.fn.jquery, "1.4") > 0);
                    if (jQueryUndefined) {
                        self.LogFirstRun('jQuery not loaded', acs.targetId);
                        self.IncludeScript(sms.jQueryJSUrl, function () { self.Init(sms, acs); });
                        self.LogFirstRun("jQuery loaded from " + sms.jQueryJSUrl, acs.targetId);
                        return;
                    } else {
                        self.LogFirstRun("jQuery already loaded: v." + jQuery.fn.jquery, acs.targetId);
                    }
                }
            }


            jQuery(function () {

                if (sms.includeScriptAndStyle) {

                    if (sms.jQueryUIJSUrl !== "") {
                        if (!jQuery.ui || self.CompareVersions(jQuery.ui.version, '1.8') > 0) {
                            if (jQuery.ui && sms.crushjQueryUI) {
                                jQuery.ui.version = undefined;
                            }
                            self.LogFirstRun('jQuery.UI not loaded', acs.targetId);
                            jQuery.getScript(sms.jQueryUIJSUrl, function (data, textStatus) { self.Init(sms, acs); });
                            self.LogFirstRun("jQuery.UI loaded from " + sms.jQueryUIJSUrl, acs.targetId);
                            return;
                        } else {
                            self.LogFirstRun("jQuery.UI already loaded: v." + jQuery.ui.version, acs.targetId);
                        }
                    }

                    if (sms.jQueryUICSSUrl !== '' && jQuery('head link[href="' + sms.jQueryUICSSUrl + '"]').length === 0) {
                        console.log('jQuery.UI CSS not loaded');
                        // V1
                        jQuery("<link></link>").appendTo(jQuery('head')).attr({ type: 'text/css', rel: 'stylesheet' }).attr('href', sms.jQueryUICSSUrl);

                        console.log("jQuery.UI CSS loaded from " + sms.jQueryUICSSUrl);
                    }
                }
                self.SetupAutocomplete(acs);
            });
        },

        IncludeScript: function (s, callback) {
            console.log('Including script ' + s);
            var script = document.createElement('script');
            script.src = s;
            var head = document.getElementsByTagName('head')[0],
		        done = false;
            // Attach handlers for all browsers
            script.onload = script.onreadystatechange = function () {
                if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
                    done = true;
                    callback();
                    script.onload = script.onreadystatechange = null;
                    head.removeChild(script);
                };
            };
            head.appendChild(script);
        },

        SetupAutocomplete: function (acs) {
            var ALSASelf = this;
            console.log("Registering custom autocomplete");

            var widgetAutocompleteOptions = {
                _renderMenu: function (ul, items) {
                    console.log("Rendering menu with " + items.length + " items");
                    var self = this,
				        currentGroup = "";
                    if (acs.group) {

                        var HTItems = {},
                                counter = 0,
                                itemsLength = items.length,
                                sortingGroup = "";

                        for (counter = 0; counter < itemsLength; counter++) {
                            sortingGroup = items[counter][acs.groupBy];
                            if (!HTItems[sortingGroup]) {
                                HTItems[sortingGroup] = counter;
                            }
                        }

                        items.sort(function (a, b) {
                            var aValue = a[acs.groupBy],
                                    bValue = b[acs.groupBy];
                            return HTItems[aValue] - HTItems[bValue];
                        });
                    }
                    if (acs.displayHeader) {
                        ul.append(jQuery("<li></li>").html(acs.headerTemplate));
                    }
                    jQuery.each(items, function (index, item) {
                        if (acs.group && item[acs.groupBy] !== currentGroup) {
                            ul.append(jQuery("<li></li>").html(ALSASelf.Template.tmpl(acs.groupingTemplate, item)));
                            currentGroup = item[acs.groupBy];
                        }
                        self._renderCustomItem(ul, item);
                    });
                    if (items.length === 0) {
                        console.log("No items returned, returning empty text");
                        ul.append(jQuery("<li></li>").html(acs.noAnswerTemplate));
                    }
                    console.log("Menu rendered with " + items.length + " items");
                },
                _renderCustomItem: function (ul, item) {
                    var templateOutput = ALSASelf.Template.tmpl(acs.itemTemplate, item);
                    if (acs.showHighlights) {
                        try { // on ne veut pas que nos données soient maltraitées par une expression régulière trop étrange
                            var regex = new RegExp('(?![^<>]*>)(' + this.term + ')', 'gi');
                            templateOutput = templateOutput.replace(regex, "<span class=\"ALS_highlight\">$1</span>");
                        } catch (e) {
                            // on ne fait rien, le highlight ne sera pas présent pour cause d'expression régulière impossible à parser
                        }
                    }
                    return jQuery("<li></li>")
			            .data("item.autocomplete", item)
						.data("ui-autocomplete-item", item)
			            .append(jQuery("<a></a>")
                        .html(templateOutput))
			            .appendTo(ul);
                },
                _response: function (content) {
                    if (!this.options.disabled && content) {
                        content = this._normalize(content);
                        this._suggest(content);
                        this._trigger("open");
                    } else {
                        this.close();
                    }
                    this.pending--;
                    if (!this.pending) {
                        this.element.removeClass("ui-autocomplete-loading");
                    }
                }
            };

            if (jQuery.ui && ALSASelf.CompareVersions(jQuery.ui.version, '1.10') <= 0) {
                delete widgetAutocompleteOptions["_response"];

                widgetAutocompleteOptions["__response"] = function (content) {
                    if (content) {
                        content = this._normalize(content);
                    }
                    this._trigger("response", null, { content: content });
                    if (!this.options.disabled && content && !this.cancelSearch) {
                        this._suggest(content);
                        this._trigger("open");
                    } else {
                        // use ._close() instead of .close() so we don't cancel future searches
                        this._close();
                    }
                }
            }

            jQuery.widget("custom.AricieLSAutoComplete", jQuery.ui.autocomplete, widgetAutocompleteOptions);
            console.log("Registering custom autocomplete done");

            console.log("Linking custom autocomplete to input");
            jQuery("#" + acs.targetId).AricieLSAutoComplete({
                minLength: acs.minlength,
                position: jQuery.parseJSON(acs.enableCustomPosition ? acs.customPosition : acs.defaultPosition),
                source: function (request, response) {
                    console.log("Calling webservice with " + request.term);
                    jQuery.ajax({
                        url: acs.webservice,
                        contentType: "application/json; charset=utf-8",
                        type: "POST",
                        data: "{ prefix: '" + escape(request.term) + "', culture: '' }",
                        dataFilter: function (data) {
                            //http://encosia.com/never-worry-about-asp-net-ajaxs-d-again/
                            var msg = eval('(' + data + ')');
                            if (msg.hasOwnProperty('d'))
                                return msg.d;
                            else
                                return msg;
                        },
                        success: function (data) {
                            if (response != undefined) {
                                response(data);
                            }
                        },
                        error: function (jqXHR, textStatus, errorThrown) {
                            console.log("Error occured");
                            console.log(jqXHR);
                            console.log(textStatus);
                            console.log(errorThrown);
                        }
                    });
                },
                select: function (event, ui) {
                    console.log("Item selected");
                    var windowName = new Function("item", acs.customWindowing)(ui.item);
                    if (windowName === null || typeof windowName !== "string") {
                        document.location = ui.item.GoToFullUrl;
                    } else {
                        window.open(ui.item.GoToFullUrl, windowName);
                    }
                }
            });
            console.log("Linking custom autocomplete to input done");

        },

        // from http://www.west-wind.com/weblog/posts/2008/Oct/13/Client-Templating-with-jQuery
        Template: (function () {
            return {
                _tmplCache: {},

                tmpl: function (str, data) {
                    var err = "";
                    try {
                        var func = this._tmplCache[str];
                        if (!func) {
                            var strFunc =
            "var p=[],print=function(){p.push.apply(p,arguments);};" +
                        "with(obj){p.push('" +
                             str.replace(/[\r\t\n]/g, " ")
                            .replace(/'(?=[^#]*#>)/g, "\t")
                            .split("'").join("\\'")
                            .split("\t").join("'")
                            .replace(/<#=(.+?)#>/g, "',$1,'")
                            .split("<#").join("');")
                            .split("#>").join("p.push('")
                            + "');}return p.join('');";

                            func = new Function("obj", strFunc);
                            this._tmplCache[str] = func;
                        }
                        return func(data);
                    } catch (e) { err = e.message; }
                    return "< # ERROR: " + err + " # >";
                }
            };
        } ())

    };

} ());

